using System.Diagnostics;

namespace rsync
{
    internal class StateStorage
    {
        private readonly int _rollbackWindow;
        private readonly StateFrameData[] _frames;

        public StateStorage(int rollbackWindowSize)
        {
            _rollbackWindow = rollbackWindowSize;
            _frames = new StateFrameData[_rollbackWindow];

            for (var i = 0; i < _rollbackWindow; i++)
            {
                _frames[i] = new StateFrameData();
            }
        }

        public void SaveFrame(int frame, byte[] stateBuffer)
        {
            Debug.Assert(frame >= 0);
            Debug.Assert(stateBuffer != null, "试图保存一个空状态!");

            _frames[frame % _rollbackWindow].Buffer = Platform.CloneByteArray(stateBuffer);
            _frames[frame % _rollbackWindow].Checksum = CaculateChecksum(stateBuffer);
        }

        public StateFrameData LoadFrame(int frame)
        {
            Debug.Assert(frame >= 0);
            Debug.Assert(_frames[frame % _rollbackWindow] != null, "尝试加载空状态!");

            return _frames[frame % _rollbackWindow];
        }

        private uint CaculateChecksum(byte[] stateBuffer)
        {
            uint stateChecksum = (uint)stateBuffer.Length;
            foreach (byte b in stateBuffer)
                stateChecksum ^= b;
            return stateChecksum;
        }
    }

    internal class StateFrameData
    {
        public byte[] Buffer;
        public uint Checksum;
    }
}
